#include "murrine_draw.h"
#include "murrine_style.h"
#include "murrine_types.h"

#include "support.h"

#include <cairo.h>

#define M_PI 3.14159265358979323846

// Static Murrine Functions
static void
murrine_rounded_rectangle (cairo_t *cr, double x, double y, double w, double h, uint8 corners)
{
	const float RADIUS_CORNERS = 0.35;

	if (corners & MRN_CORNER_TOPLEFT)
		cairo_move_to (cr, x+RADIUS_CORNERS, y);
	else
		cairo_move_to (cr, x, y);
	
	if (corners & MRN_CORNER_TOPRIGHT) {
		cairo_line_to (cr, x+w-RADIUS_CORNERS, y);
		cairo_move_to (cr, w+x, y+RADIUS_CORNERS);
	}
	else
		cairo_line_to (cr, x+w, y);
		
	if (corners & MRN_CORNER_BOTTOMRIGHT) {
		cairo_line_to (cr, w+x, h+y-RADIUS_CORNERS);
		cairo_move_to (cr, w+x-RADIUS_CORNERS, h+y);
	}
	else
		cairo_line_to (cr, w+x, h+y);
	
	if (corners & MRN_CORNER_BOTTOMLEFT) {
		cairo_line_to (cr, x+RADIUS_CORNERS, h+y);
		cairo_move_to (cr, x, h+y-RADIUS_CORNERS);
	}
	else
		cairo_line_to (cr, x, h+y);
	
	if (corners & MRN_CORNER_TOPLEFT)
		cairo_line_to (cr, x, y+RADIUS_CORNERS);
	else {
		if (corners == MRN_CORNER_NONE)
			cairo_close_path (cr);
		else
			cairo_line_to (cr, x, y);
	}
}

static void
clearlooks_rounded_rectangle (cairo_t *cr,
                                 double x, double y, double w, double h,
                                 int radius, uint8 corners)
{
	if (corners & MRN_CORNER_TOPLEFT)
		cairo_move_to (cr, x+radius, y);
	else
		cairo_move_to (cr, x, y);
	
	if (corners & MRN_CORNER_TOPRIGHT)
		cairo_arc (cr, x+w-radius, y+radius, radius, M_PI * 1.5, M_PI * 2);
	else
		cairo_line_to (cr, x+w, y);
	
	if (corners & MRN_CORNER_BOTTOMRIGHT)
		cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI * 0.5);
	else
		cairo_line_to (cr, x+w, y+h);
	
	if (corners & MRN_CORNER_BOTTOMLEFT)
		cairo_arc (cr, x+radius,   y+h-radius, radius, M_PI * 0.5, M_PI);
	else
		cairo_line_to (cr, x, y+h);
	
	if (corners & MRN_CORNER_TOPLEFT)
		cairo_arc (cr, x+radius,   y+radius,   radius, M_PI, M_PI * 1.5);
	else
		cairo_line_to (cr, x, y);
}

static void murrine_draw_flat_hilight (cairo_t *cr, int x, int y, int width, int height)
{
	cairo_rectangle (cr, x, y, width, height/2);
}

static void murrine_draw_curved_hilight (cairo_t *cr,
                                 double curve_pos, int width, int height)
{
	cairo_move_to(cr, curve_pos, height-curve_pos);
	cairo_curve_to(cr, curve_pos, height/2+height/5, height/5, height/2, height/2, height/2);
	cairo_line_to(cr, width-height/2, height/2);
	cairo_curve_to(cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2-height/5, width-curve_pos, curve_pos);
	cairo_line_to(cr, curve_pos, curve_pos);
	cairo_line_to(cr, curve_pos, height-curve_pos);
	cairo_close_path(cr);
}

static void murrine_draw_curved_hilight_neg (cairo_t *cr,
                                 double curve_pos, int width, int height)
{
	cairo_move_to(cr, curve_pos, curve_pos);
	cairo_curve_to(cr, curve_pos, height/2-height/5, height/5, height/2, height/2, height/2);
	cairo_line_to(cr, width-height/2, height/2);
	cairo_curve_to(cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2-height/5, width-curve_pos, curve_pos);
	cairo_close_path(cr);
}

static void murrine_draw_curved_hilight_bottom_neg (cairo_t *cr,
                                 double curve_pos, int width, int height)
{
	cairo_move_to(cr, curve_pos, height-curve_pos);
	cairo_curve_to(cr, curve_pos, height/2+height/5, height/5, height/2, height/2, height/2);
	cairo_line_to(cr, width-height/2, height/2);
	cairo_curve_to(cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2+height/5, width-curve_pos, height-curve_pos);
	cairo_close_path(cr);
}


static void
rotate_mirror_translate (cairo_t *cr, double radius, double x, double y,
                         boolean mirror_horizontally, boolean mirror_vertically)
{
	cairo_matrix_t matrix_rotate;
	cairo_matrix_t matrix_mirror;
	cairo_matrix_t matrix_result;
	
	double r_cos = cos(radius);
	double r_sin = sin(radius);
	
	cairo_matrix_init (&matrix_rotate, r_cos, r_sin, r_sin, r_cos, x, y);
	
	cairo_matrix_init (&matrix_mirror, mirror_horizontally ? -1 : 1, 0, 0,
	                                   mirror_vertically ? -1 : 1, 0, 0);

	cairo_matrix_multiply (&matrix_result, &matrix_mirror, &matrix_rotate);

	cairo_set_matrix (cr, &matrix_result);
}


// Widget Functions
void
murrine_draw_button (cairo_t *cr,
                        const MurrineColors *colors,
                        const WidgetParameters *widget,
                        int x, int y, int width, int height)
{
	double xoffset = 0, yoffset = 0;
	const MurrineRGB *fill            = &colors->bg[widget->state_type];
	const MurrineRGB *border_normal_  = &colors->shade[6];
	const MurrineRGB *border_disabled_ = &colors->shade[4];

	MurrineRGB border_normal;
	murrine_shade (border_normal_, &border_normal, 0.95);

	MurrineRGB border_disabled = *border_disabled_;

	MurrineRGB hilight;
	murrine_shade (fill, &hilight, 1.1*widget->hilight_ratio);

	cairo_translate (cr, x, y);
	cairo_set_line_width (cr, 1.0);

	if (widget->xthickness == 3)
		xoffset = 1;
	if (widget->ythickness == 3)
		yoffset = 1;

	if (widget->disabled)
	{
		//the shadow
		if (widget->roundness < 2)
			murrine_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->corners);
		else
			clearlooks_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
		cairo_set_source_rgba (cr, border_disabled.r, border_disabled.g, border_disabled.b, 0.15);
		cairo_stroke(cr);
		//the border
		border_disabled.r = border_disabled.r * (0.6) + fill->r * 0.4;
		border_disabled.g = border_disabled.g * (0.6) + fill->g * 0.4;
		border_disabled.b = border_disabled.b * (0.6) + fill->b * 0.4;
	}
	else
	{
		//the shadow 
		if (widget->roundness < 2)
			murrine_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->corners);
		else
			clearlooks_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
		cairo_set_source_rgba (cr, border_normal.r, border_normal.g, border_normal.b, 0.15);
		cairo_stroke(cr);		
		//the border
		border_normal.r = border_normal.r * (0.6) + fill->r * 0.4;
		border_normal.g = border_normal.g * (0.6) + fill->g * 0.4;
		border_normal.b = border_normal.b * (0.6) + fill->b * 0.4;
	}
	
	//fill
	cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
	if (widget->roundness < 2)
		cairo_rectangle(cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);		
	else
		clearlooks_rounded_rectangle(cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
	
	cairo_save(cr);
	if (widget->roundness > 1)
		cairo_clip_preserve(cr);

	int curve_pos = 1;
	if (widget->glazestyle > 0) {
		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
		if (widget->glazestyle == 2)
			cairo_fill_preserve(cr);
		else
			cairo_fill(cr);
		if (widget->roundness < 2)
			curve_pos = 2;
		if (width<height) {
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
			if (widget->glazestyle < 3)
				murrine_draw_curved_hilight (cr, curve_pos, height, width);
			else
				murrine_draw_curved_hilight_neg (cr, curve_pos, height, width);
		}
		else
			if (widget->glazestyle < 3)
				murrine_draw_curved_hilight (cr, curve_pos, width, height);
			else
				murrine_draw_curved_hilight_neg (cr, curve_pos, width, height);
	}
	else {
		cairo_fill(cr);
		if ((float)width/height<0.5) {
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
			murrine_draw_flat_hilight (cr, xoffset + 1, yoffset + 1, (height-(yoffset*2)-2), width-(xoffset*2)-2);
		}
		else
			murrine_draw_flat_hilight (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
	}
	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8);
	cairo_fill(cr);

	if (widget->glazestyle == 4) {
		if (width<height) {
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
			murrine_draw_curved_hilight_bottom_neg (cr, curve_pos, height, width);
		}
		else
			murrine_draw_curved_hilight_bottom_neg (cr, curve_pos, width, height);
		MurrineRGB shadow;
		murrine_shade (fill, &shadow, 0.96*(1/widget->hilight_ratio));
		cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
		cairo_fill(cr);
	}

	murrine_shade (fill, &hilight, 1.08*widget->hilight_ratio); //makes the inner border brighter
	//the white inner border
	if (widget->roundness < 2) {
		int tmp;
		if ((float)width/height<0.5 || widget->glazestyle > 0 && width<height) {
			tmp = height;
			height = width;
			width = tmp;
		}
		cairo_rectangle(cr, xoffset + 1.5, yoffset + 1.5, width-(xoffset*2)-3, height-(yoffset*2)-3);		
		cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke(cr);
		//bottom line
		cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
		cairo_move_to (cr, xoffset+1, height-yoffset-1.5);
		cairo_rel_line_to (cr, width-(xoffset*2)-2, 0);
		if (widget->glazestyle == 2) {
			cairo_move_to (cr, width-(xoffset)-1.5, yoffset+2);
			cairo_rel_line_to (cr, 0, height-yoffset*2-3.5);
		}
		cairo_stroke (cr);
		if (tmp == width) {
			tmp = height;
			height = width;
			width = tmp;
		}
	}
	cairo_reset_clip(cr);
	cairo_restore(cr);
	//border
	if (widget->disabled)
		cairo_set_source_rgb (cr, border_disabled.r, border_disabled.g, border_disabled.b);
	else
		cairo_set_source_rgb (cr, border_normal.r, border_normal.g, border_normal.b);
	if (widget->roundness < 2)
		murrine_rounded_rectangle(cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->corners);
	else
		clearlooks_rounded_rectangle(cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
	cairo_stroke(cr);
}

void
murrine_draw_entry (cairo_t *cr,
                       const MurrineColors *colors,
                       const WidgetParameters *widget,
                       int x, int y, int width, int height)
{
	MurrineRGB *base = (MurrineRGB*)&colors->base[widget->state_type];
	MurrineRGB *border;
	
	if (widget->focus)
		border = (MurrineRGB*)&colors->spot[2];
	else
		border = (MurrineRGB*)&colors->shade[widget->disabled ? 3 : 5];

	cairo_translate (cr, x+0.5, y+0.5);
	cairo_set_line_width (cr, 1.0);
	
	/* Fill the background (shouldn't have to) */
	cairo_rectangle (cr, -0.5, -0.5, width, height);
	cairo_set_source_rgb (cr, widget->parentbg.r, widget->parentbg.g, widget->parentbg.b);
	cairo_fill (cr);

	/* Fill the entry's base color (why isn't is large enough by default?) */
	cairo_rectangle (cr, 1.5, 1.5, width-4, height-4);
	cairo_set_source_rgb (cr, base->r, base->g, base->b);
	cairo_fill (cr);
	
	/* Draw the border */
	cairo_set_source_rgb (cr, border->r, border->g, border->b);
	if (widget->roundness<2)
		cairo_rectangle (cr, 1, 1, width-3, height-3);
	else
		if (widget->roundness == 2)
			clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, 2, widget->corners);
		else
			clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, 3, widget->corners);
	cairo_stroke (cr);

	/* Draw the focused border */
	if (widget->focus)
	{
		if (widget->roundness<2)
			cairo_rectangle (cr, 2, 2, width-5, height-5);
		else
			clearlooks_rounded_rectangle (cr, 2, 2, width-5, height-5, 2, widget->corners);
		cairo_set_source_rgb (cr, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);
		cairo_stroke (cr);
	}
}

void
murrine_draw_spinbutton_down (cairo_t *cr,
                                 const MurrineColors *colors,
                                 const WidgetParameters *widget,
                                 int x, int y, int width, int height)
{
	cairo_pattern_t *pattern;
	
	cairo_translate (cr, x+1, y+1);
	
	cairo_rectangle (cr, 1, 1, width-4, height-4);
	
	cairo_set_source_rgb (cr, colors->bg[widget->state_type].r,
	                          colors->bg[widget->state_type].g, 
	                          colors->bg[widget->state_type].b);

	cairo_fill_preserve (cr);
	
	pattern = cairo_pattern_create_linear (0, 0, 0, height);
	cairo_pattern_add_color_stop_rgba (pattern, 0.0, 0.0, 0.0, 0.0, 0.3);
	cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0.0, 0.0, 0.0, 0.0);
	
	cairo_set_source (cr, pattern); 
	cairo_fill (cr);
	
	cairo_pattern_destroy (pattern);
}

static void
murrine_scale_draw_gradient (cairo_t *cr,
                                const MurrineRGB *c1,
                                const MurrineRGB *c2,
                                int x, int y, int width, int height,
                                boolean horizontal)
{
	cairo_set_source_rgb (cr, c1->r, c1->g, c1->b);

	cairo_rectangle (cr, x, y, width, height);	
	cairo_fill (cr);
	
	cairo_rectangle (cr, x, y, width, height);	
	cairo_set_source_rgba (cr, c2->r, c2->g, c2->b, 0.6);
	cairo_stroke (cr);
}

void
murrine_draw_scale_trough (cairo_t *cr,
                              const MurrineColors *colors,
                              const WidgetParameters *widget,
                              const SliderParameters *slider,
                              int x, int y, int width, int height)
{
	int     fill_x, fill_y, fill_width, fill_height; /* Fill x,y,w,h	 */
	int     trough_width, trough_height;
	double  translate_x, translate_y;
	int     fill_size = slider->fill_size;
	int			TROUGH_SIZE = 6;

	if (slider->horizontal)
	{
		if (fill_size > width-3)
			fill_size = width-3;

		fill_x        = slider->inverted ? width - fill_size - 3 : 0;
		fill_y        = 0;
		fill_width    = fill_size;			
		fill_height   = TROUGH_SIZE-2;
		
		trough_width  = width-3;
		trough_height = TROUGH_SIZE-2;
		
		translate_x   = x + 0.5;
		translate_y   = y + 0.5 + (height/2) - (TROUGH_SIZE/2);
	}
	else
	{
		if (fill_size > height-3)
			fill_size = height-3;

		fill_x        = 0;
		fill_y        = slider->inverted ? height - fill_size - 3 : 0;
		fill_width    = TROUGH_SIZE-2;
		fill_height   = fill_size;			
		
		trough_width  = TROUGH_SIZE-2;
		trough_height = height-3;
		
		translate_x   = x + 0.5 + (width/2) - (TROUGH_SIZE/2);
		translate_y  = y + 0.5;
	}

	cairo_set_line_width (cr, 1.0);
	cairo_translate (cr, translate_x, translate_y);
	
	cairo_translate (cr, 1, 1);
	murrine_scale_draw_gradient (cr, &colors->shade[1],
	                                    &colors->shade[3], /* border */
	                                    0, 0, trough_width, trough_height,
	                                    slider->horizontal);
	
	murrine_scale_draw_gradient (cr, &colors->spot[1],
	                                    &colors->spot[2], /* border */
	                                    fill_x, fill_y, fill_width, fill_height,
	                                    slider->horizontal);
}

void
murrine_draw_progressbar_trough (cairo_t *cr,
                                    const MurrineColors *colors,
                                    const WidgetParameters *widget,
                                    int x, int y, int width, int height)
{
	MurrineRGB      *border = (MurrineRGB*)&colors->shade[3];
	
	cairo_set_line_width (cr, 1.0);
	
	/* Fill with bg color */
	cairo_set_source_rgb (cr, colors->bg[widget->state_type].r,
	                          colors->bg[widget->state_type].g,
	                          colors->bg[widget->state_type].b);
	
	cairo_rectangle (cr, x, y, width, height);	
	cairo_fill (cr);

	/* Create trough box */
	cairo_rectangle (cr, x+1, y+1, width-2, height-2);
	cairo_set_source_rgb (cr, colors->shade[1].r, colors->shade[1].g, colors->shade[1].b );
	cairo_fill (cr);

	/* Draw border */
	cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
	cairo_set_source_rgba (cr, border->r, border->g, border->b, 0.8);
	cairo_stroke (cr);
}

void
murrine_draw_progressbar_fill (cairo_t *cr,
                                  const MurrineColors *colors,
                                  const WidgetParameters *widget,
                                  const ProgressBarParameters *progressbar,
                                  int x, int y, int width, int height,
                                  gint offset)
{
	boolean		is_horizontal = progressbar->orientation < 2;
	double		tile_pos = 0;
	double		stroke_width;
	int			  x_step;

	cairo_rectangle (cr, x, y, width, height);

	if (is_horizontal)
	{
		if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
			rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
		else
			rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
	}
	else
	{
		int tmp = height;
		height  = width;
		width   = tmp;
		
		//trying a little fix 
    x = x + 1;
    y = y - 1;
    width = width + 2;
    height = height - 2;
      
		if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
		else
			rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
	}
	
	cairo_save (cr);
  cairo_clip (cr);  	
	
	stroke_width = height*2;
	x_step = (((float)stroke_width/10)*offset);
	cairo_set_line_width (cr, 1.0);
	cairo_save (cr);
	cairo_rectangle (cr, 1.5, 0.5, width-2, height-1);

	MurrineRGB hilight;
	murrine_shade (&colors->spot[1], &hilight, 1.1*widget->hilight_ratio);

	/* Draw fill */
	cairo_set_source_rgb (cr, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);
		
	if (widget->glazestyle > 0) {
		if (widget->glazestyle == 2)
			cairo_fill_preserve (cr);
		else
			cairo_fill(cr); 
		//rounded fill
		if (widget->glazestyle < 3)
			murrine_draw_curved_hilight (cr, 1.5, width, height);
		else
			murrine_draw_curved_hilight_neg (cr, 1.5, width, height);
	}
	else {
		cairo_fill(cr);
		murrine_draw_flat_hilight (cr, 1.5, 0.5, width-2, height);
	}
	
	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8);
	cairo_fill (cr);

	if (widget->glazestyle == 4) {
		murrine_draw_curved_hilight_bottom_neg (cr, 1.5, width, height+1);
		MurrineRGB shadow;
		murrine_shade (&colors->spot[1], &shadow, 0.96*(1/widget->hilight_ratio));
		cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
		cairo_fill(cr);
	}

	if (widget->glazestyle == 2) {
		cairo_move_to (cr, 2.5, height-2);
		cairo_line_to (cr, 2.5, 2);
		cairo_move_to (cr, 2, 1.5);
		cairo_line_to (cr, width-2, 1.5);
		cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke (cr);
		cairo_move_to (cr, width-2.5, 2);
		cairo_line_to (cr, width-2.5, height-2);
		cairo_move_to (cr, width-2, height-1.5);
		cairo_line_to (cr, 2, height-1.5);
		cairo_set_source_rgb (cr, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);
		cairo_stroke (cr);
	}	
	
	/* Draw strokes */
	while (tile_pos <= width+x_step-2)
	{
		cairo_move_to (cr, stroke_width/2-x_step, 0);
		cairo_line_to (cr, stroke_width-x_step,   0);
		cairo_line_to (cr, stroke_width/2-x_step, height);
		cairo_line_to (cr, -x_step, height);
		
		cairo_translate (cr, stroke_width, 0);
		tile_pos += stroke_width;
	}

	cairo_set_source_rgba (cr, colors->spot[2].r, colors->spot[2].g,  colors->spot[2].b, 0.15);
	cairo_fill (cr);
	cairo_restore (cr);
	
	// Damn Border!!!
	cairo_set_source_rgba (cr, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0.8);
	cairo_rectangle (cr, 1.5, 0.5, width-3, height-1);
   
	// Stroke the Damn Border!!!
	cairo_stroke (cr);
}

void
murrine_draw_optionmenu (cairo_t *cr,
                            const MurrineColors *colors,
                            const WidgetParameters *widget,
                            const OptionMenuParameters *optionmenu,
                            int x, int y, int width, int height)
{
	int offset = widget->ythickness + 1;
	
	murrine_draw_button (cr, colors, widget, x, y, width, height);

	//Separator
	MurrineRGB *dark   = (MurrineRGB*)&colors->shade[6];
	
	cairo_set_line_width  (cr, 1.0);
	cairo_translate       (cr, optionmenu->linepos+0.5, 1);
	
	cairo_move_to         (cr, 0.0, offset);
	cairo_line_to         (cr, 0.0, height - offset - widget->ythickness + 1);
	cairo_set_source_rgba (cr, dark->r, dark->g, dark->b, 0.4);
	cairo_stroke          (cr);
}

void
murrine_draw_menubar (cairo_t *cr,
                         const MurrineColors *colors,
                         const WidgetParameters *widget,
                         int x, int y, int width, int height,
						 		 int menubarstyle)
{
	cairo_translate (cr, x, y);
	cairo_rectangle (cr, 0, 0, width, height);

	//glass menubar
	if (menubarstyle == 1) {
		MurrineRGB hilight;
		cairo_set_source_rgb (cr, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b);
		murrine_shade (&colors->bg[0], &hilight, 1.1*widget->hilight_ratio);

		if (widget->glazestyle > 0) {
			if (widget->glazestyle == 2)
				cairo_fill_preserve (cr);
			else
				cairo_fill(cr); 
			//rounded fill
			if (widget->glazestyle < 3)
				murrine_draw_curved_hilight (cr, 0, width, height);
			else
				murrine_draw_curved_hilight_neg (cr, 0, width, height);
		}
		else {
			cairo_fill(cr);
			murrine_draw_flat_hilight (cr, 0, 0, width, height);
		}
		cairo_set_source_rgba 	(cr, hilight.r, hilight.g, hilight.b, 0.8);
		cairo_fill 				 	(cr);

		if (widget->glazestyle == 4) {
			murrine_draw_curved_hilight_bottom_neg (cr, 0, width, height);
			MurrineRGB shadow;
			murrine_shade (&colors->bg[0], &shadow, 0.96*(1/widget->hilight_ratio));
			cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
			cairo_fill(cr);
		}

		if (widget->glazestyle == 2) {
			cairo_set_line_width (cr, 1.0);
			cairo_move_to (cr, 1.5, height-2);
			cairo_line_to (cr, 1.5, 1);
			cairo_move_to (cr, 1, 1.5);
			cairo_line_to (cr, width-1, 1.5);
			cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
			cairo_stroke (cr);
			cairo_move_to (cr, width-1.5, 2);
			cairo_line_to (cr, width-1.5, height-2);
			cairo_move_to (cr, width-1, height-1.5);
			cairo_line_to (cr, 1, height-1.5);
			cairo_set_source_rgb (cr, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b);
			cairo_stroke (cr);
		}	
	}
	//gradient menubar
	if (menubarstyle == 2) {
		cairo_pattern_t *pattern;
		MurrineRGB lower;
		murrine_shade (&colors->bg[0], &lower, 0.95);
		pattern = cairo_pattern_create_linear (0, 0, 0, height);
		cairo_pattern_add_color_stop_rgb (pattern, 0.0, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b);
		cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r, lower.g, lower.b);
		cairo_set_source (cr, pattern);
		cairo_fill (cr);
		cairo_pattern_destroy 	(pattern);
	}
	//striped menubar
	if (menubarstyle == 3) {
		cairo_pattern_t *pattern;
		MurrineRGB lower;
		murrine_shade (&colors->bg[0], &lower, 0.8);
		pattern = cairo_pattern_create_linear (0, 0, 0, height);
		cairo_pattern_add_color_stop_rgb (pattern, 0.0, lower.r, lower.g, lower.b);
		cairo_pattern_add_color_stop_rgb (pattern, 1.0, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b);
		cairo_set_source (cr, pattern);
		cairo_fill (cr);
		cairo_pattern_destroy 	(pattern);
		int counter = -height;
		cairo_set_line_width  (cr, 1.0);
		murrine_shade (&colors->bg[0], &lower, 0.9);
		cairo_set_source_rgb  (cr, lower.r, lower.g, lower.b);
		while (counter < width) {
			cairo_move_to     (cr, counter, height);
			cairo_line_to     (cr, counter+height, 0);
			cairo_stroke      (cr);
			counter += 5;
		}
	}
	else {
		//flat menubar
		cairo_set_source_rgb (cr, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b);
		cairo_fill (cr);
	}
	
	/* Draw bottom line */
	if (menubarstyle == 1 && widget->glazestyle == 2)
		cairo_rectangle(cr, 0.5, 0.5, width-1, height-1);
#ifndef HAVE_MACMENU	
	else {
		cairo_set_line_width  (cr, 1.0);
		cairo_move_to         (cr, 0, height-0.5);
		cairo_line_to         (cr, width, height-0.5);
	}
	cairo_set_source_rgb  (cr, colors->shade[3].r, colors->shade[3].g, colors->shade[3].b);
	cairo_stroke          (cr);
#endif
}

static void
murrine_get_frame_gap_clip (int x, int y, int width, int height, 
                               FrameParameters     *frame,
                               MurrineRectangle *bevel,
                               MurrineRectangle *border)
{
	if (frame->gap_side == MRN_GAP_TOP)
	{
		MURRINE_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  -0.5,
											 frame->gap_width - 3, 2.0);
		MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  -0.5,
											 frame->gap_width - 2, 2.0);
	}
	else if (frame->gap_side == MRN_GAP_BOTTOM)
	{
		MURRINE_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  height - 2.5,
											 frame->gap_width - 3, 2.0);
		MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  height - 1.5,
											 frame->gap_width - 2, 2.0);		
	}
	else if (frame->gap_side == MRN_GAP_LEFT)
	{
		MURRINE_RECTANGLE_SET ((*bevel),  -0.5, 1.5 + frame->gap_x,
											 2.0, frame->gap_width - 3);
		MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x,
											 1.0, frame->gap_width - 2);			
	}
	else if (frame->gap_side == MRN_GAP_RIGHT)
	{
		MURRINE_RECTANGLE_SET ((*bevel),  width - 2.5, 1.5 + frame->gap_x,
											 2.0, frame->gap_width - 3);
		MURRINE_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x,
											 1.0, frame->gap_width - 2);			
	}
}

void
murrine_draw_frame            (cairo_t *cr,
                                  const MurrineColors     *colors,
                                  const WidgetParameters     *widget,
                                  const FrameParameters      *frame,
                                  int x, int y, int width, int height)
{
	MurrineRGB *border = frame->border;
	MurrineRectangle bevel_clip;
	MurrineRectangle frame_clip;

	if (frame->shadow == MRN_SHADOW_NONE)
		return;
	
	if (frame->gap_x != -1)
		murrine_get_frame_gap_clip (x, y, width, height,
		                               (FrameParameters*)frame,
		                               &bevel_clip, &frame_clip);
	
	cairo_set_line_width (cr, 1.0);
	cairo_translate      (cr, x+0.5, y+0.5);
	
	/* save everything */
  cairo_save (cr);
  	
	/* Set clip for the bevel */
	if (frame->gap_x != -1)
	{
		/* Set clip for gap */
		cairo_set_fill_rule  (cr, CAIRO_FILL_RULE_EVEN_ODD);
		cairo_rectangle      (cr, -0.5, -0.5, width, height);
		cairo_rectangle      (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
		cairo_clip           (cr);
	}
	
	cairo_restore    (cr);
	cairo_save       (cr);
	
	/* Set clip for the frame */
	cairo_reset_clip     (cr);
	if (frame->gap_x != -1)
	{
		/* Set clip for gap */
		cairo_set_fill_rule  (cr, CAIRO_FILL_RULE_EVEN_ODD);
		cairo_rectangle      (cr, -0.5, -0.5, width, height);
		cairo_rectangle      (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
		cairo_clip           (cr);
	}

	/* Draw frame */
	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
	{
		cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.2 );
		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
			cairo_rectangle       (cr, 0, 0, width-2, height-2);
		else
			cairo_rectangle       (cr, 1, 1, width-2, height-2);
	}
	else
	{
		cairo_set_source_rgb (cr, border->r, border->g, border->b );
		cairo_rectangle      (cr, 0, 0, width-1, height-1);
	}
	cairo_stroke     (cr);
	cairo_restore    (cr);
}

void
murrine_draw_tab (cairo_t *cr,
                     const MurrineColors *colors,
                     const WidgetParameters *widget,
                     const TabParameters    *tab,
                     int x, int y, int width, int height)
{
	const float RADIUS = 3.0;
	MurrineRGB          *stripe_fill   = (MurrineRGB*)&colors->spot[1];
	MurrineRGB          *stripe_border = (MurrineRGB*)&colors->spot[2];
	MurrineRGB          *fill;
	MurrineRGB          *border1;

	cairo_pattern_t		*pattern;

	int                  corners;
	double               strip_size;

	if (!widget->active)
		border1 = (MurrineRGB*)&colors->shade[5];
	else
		border1 = (MurrineRGB*)&colors->shade[4];

	/* Set clip */
	cairo_rectangle      (cr, x, y, width, height);
	cairo_clip           (cr);
	cairo_new_path       (cr);

	/* Translate and set line width */	
	cairo_set_line_width (cr, 1.0);
	cairo_translate      (cr, x+0.5, y+0.5);

	/* Make the tabs slightly bigger than they should be, to create a gap */
	/* And calculate the strip size too, while you're at it */
	if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
	{
		height += RADIUS;
	 	strip_size = ((100.0/height)*2.0)/100.0;
		
		if (tab->gap_side == MRN_GAP_TOP)
		{
			cairo_translate (cr, 0.0, -4.0); /* gap at the other side */
			corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
		}
		else
			corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
	}
	else
	{
		width += RADIUS;
	 	strip_size = ((100.0/width)*2.0)/100.0;
		
		if (tab->gap_side == MRN_GAP_LEFT) 
		{
			cairo_translate (cr, -4.0, 0.0); /* gap at the other side */
			corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;		
		}
		else
			corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;	
	}
	
	/* Set the fill color */
	if (widget->active)
	fill = (MurrineRGB*)&colors->bg[widget->state_type];
	else
		fill = (MurrineRGB*)&widget->parentbg; //*/
	
	/* Set tab shape */
	if (widget->roundness < 2)	
		cairo_rectangle (cr, 0, 0, width-1, height-1);
	else
		clearlooks_rounded_rectangle  (cr, 0, 0, width-1, height-1, widget->roundness, corners);
	
	/* Draw fill */
	cairo_set_source_rgb  (cr, fill->r, fill->g, fill->b);
	cairo_fill   (cr);
	
	if (widget->active)
	{
		cairo_set_line_width (cr, 1);
		cairo_set_source_rgba (cr, colors->shade[0].r, colors->shade[0].g, colors->shade[0].b, 0.2);
		
		//if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
		if (widget->roundness < 2)
			cairo_rectangle (cr, 1, 1, width-3, height-3);
		else
			clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, widget->roundness, corners);
		
		cairo_stroke (cr);
	}
	else
	{
		/* Draw shade */
		pattern = cairo_pattern_create_linear ( tab->gap_side == MRN_GAP_LEFT   ? width-2  : 0,
		                                        tab->gap_side == MRN_GAP_TOP    ? height-2 : 0,
		                                        tab->gap_side == MRN_GAP_RIGHT  ? width    : 0,
		                                        tab->gap_side == MRN_GAP_BOTTOM ? height   : 0 );
	
		if (widget->roundness < 2)	
			cairo_rectangle (cr, 0, 0, width-1, height-1);
		else
			clearlooks_rounded_rectangle  (cr, 0, 0, width-1, height-1, widget->roundness, corners);

		cairo_pattern_add_color_stop_rgb  (pattern, 0.0,        stripe_fill->r, stripe_fill->g, stripe_fill->b);
		cairo_pattern_add_color_stop_rgb  (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
		cairo_pattern_add_color_stop_rgb  (pattern, strip_size, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b);
		cairo_set_source (cr, pattern);
		cairo_fill (cr);
		cairo_pattern_destroy (pattern);
	}

	if (widget->corners == MRN_CORNER_NONE)
		cairo_rectangle (cr, 0, 0, width-1, height-1);
	else
		if (widget->roundness < 2)
			murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, corners);
		else
			clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);

	if (widget->active)
	{
		cairo_set_source_rgb  (cr, border1->r, border1->g, border1->b);	
		cairo_stroke (cr);
	}
	else
	{
		pattern = cairo_pattern_create_linear ( tab->gap_side == MRN_GAP_LEFT   ? width-2  : 2,
		                                        tab->gap_side == MRN_GAP_TOP    ? height-2 : 2,
		                                        tab->gap_side == MRN_GAP_RIGHT  ? width    : 2,
		                                        tab->gap_side == MRN_GAP_BOTTOM ? height   : 2 );
		
		cairo_pattern_add_color_stop_rgb (pattern, 0.0,        stripe_border->r, stripe_border->g, stripe_border->b);
		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
		cairo_pattern_add_color_stop_rgb (pattern, 0.6,        border1->r,       border1->g,       border1->b);
		cairo_set_source (cr, pattern);
		cairo_stroke (cr);
		cairo_pattern_destroy (pattern);
	}
}

void
murrine_draw_separator (cairo_t *cr,
                           const MurrineColors     *colors,
                           const WidgetParameters     *widget,
                           const SeparatorParameters  *separator,
                           int x, int y, int width, int height)
{
	MurrineRGB *dark   = (MurrineRGB*)&colors->shade[3];
	MurrineRGB hilight; 
	murrine_shade (dark, &hilight, 1.5);
	
	if (separator->horizontal)
	{
		cairo_set_line_width  (cr, 1.0);
		cairo_translate       (cr, x, y+0.5);
		
		cairo_move_to         (cr, 0.0,     0.0);
		cairo_line_to         (cr, width+1, 0.0);
		cairo_set_source_rgb  (cr, dark->r, dark->g, dark->b);
		cairo_stroke          (cr);

#ifndef HAVE_MACMENU
		cairo_move_to         (cr, 0.0,   1.0);
		cairo_line_to         (cr, width, 1.0);
		cairo_set_source_rgb  (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke          (cr);			
#endif	
	}
	else
	{
		cairo_set_line_width  (cr, 1.0);
		cairo_translate       (cr, x+0.5, y);
		
		cairo_move_to         (cr, 0.0, 0.0);
		cairo_line_to         (cr, 0.0, height);
		cairo_set_source_rgb  (cr, dark->r, dark->g, dark->b);
		cairo_stroke          (cr);

#ifndef HAVE_MACMENU
		cairo_move_to         (cr, 1.0, 0.0);
		cairo_line_to         (cr, 1.0, height);
		cairo_set_source_rgb  (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke          (cr);	
#endif	
	}
}

//A special separator for combos...
G_GNUC_INTERNAL void
murrine_draw_combo_separator (cairo_t *cr,
                           const MurrineColors     *colors,
                           const WidgetParameters     *widget,
                           int x, int y, int width, int height)
{
	MurrineRGB *dark   = (MurrineRGB*)&colors->shade[6];
	
	cairo_set_line_width  (cr, 1.0);
	cairo_translate       (cr, x+0.5, y);
	
	cairo_move_to         (cr, 0.0, 0.0);
	cairo_line_to         (cr, 0.0, height+1);
	cairo_set_source_rgba (cr, dark->r, dark->g, dark->b, 0.4);
	cairo_stroke          (cr);
}

void
murrine_draw_slider_button (cairo_t *cr,
                               const MurrineColors *colors,
                               const WidgetParameters *widget,
                               const SliderParameters *slider,
                               int x, int y, int width, int height)
{
	double xoffset = 0, yoffset = 0;
	const MurrineRGB *fill            = &colors->bg[widget->state_type];
	const MurrineRGB *border_normal_  = &colors->shade[6];
	const MurrineRGB *border_disabled_ = &colors->shade[4];

	MurrineRGB border_normal;
	murrine_shade (border_normal_, &border_normal, 0.95);

	MurrineRGB border_disabled = *border_disabled_;

	MurrineRGB hilight;
	murrine_shade (fill, &hilight, 1.1*widget->hilight_ratio);

	cairo_translate (cr, x, y);
	cairo_set_line_width (cr, 1.0);

	if (widget->xthickness == 3)
		xoffset = 1;
	if (widget->ythickness == 3)
		yoffset = 1;

	if (widget->disabled)
	{
		//the shadow
		if (widget->roundness < 2)
			murrine_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->corners);
		else
			clearlooks_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
		cairo_set_source_rgba (cr, border_disabled.r, border_disabled.g, border_disabled.b, 0.15);
		cairo_stroke(cr);
		//the border
		border_disabled.r = border_disabled.r * (0.6) + fill->r * 0.4;
		border_disabled.g = border_disabled.g * (0.6) + fill->g * 0.4;
		border_disabled.b = border_disabled.b * (0.6) + fill->b * 0.4;
	}
	else
	{
		//the shadow 
		if (widget->roundness < 2)
			murrine_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->corners);
		else
			clearlooks_rounded_rectangle(cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
		cairo_set_source_rgba (cr, border_normal.r, border_normal.g, border_normal.b, 0.15);
		cairo_stroke(cr);		
		//the border
		border_normal.r = border_normal.r * (0.6) + fill->r * 0.4;
		border_normal.g = border_normal.g * (0.6) + fill->g * 0.4;
		border_normal.b = border_normal.b * (0.6) + fill->b * 0.4;
	}
	
	//fill
	cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
	if (widget->roundness < 2)
		cairo_rectangle(cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);		
	else
		clearlooks_rounded_rectangle(cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
	
	cairo_save(cr);
	if (widget->roundness > 1)
		cairo_clip_preserve(cr);

	int curve_pos = 1;
	if (widget->glazestyle > 0) {
		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
		if (widget->glazestyle == 2)
			cairo_fill_preserve(cr);
		else
			cairo_fill(cr);
		if (widget->roundness < 2)
			curve_pos = 2;
		if (!slider->horizontal) {
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
			if (widget->glazestyle < 3)
				murrine_draw_curved_hilight (cr, curve_pos, height, width);
			else
				murrine_draw_curved_hilight_neg (cr, curve_pos, height, width);
		}
		else
			if (widget->glazestyle < 3)
				murrine_draw_curved_hilight (cr, curve_pos, width, height);
			else
				murrine_draw_curved_hilight_neg (cr, curve_pos, width, height);
	}
	else {
		cairo_fill(cr);
		if (!slider->horizontal) {
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
			murrine_draw_flat_hilight (cr, xoffset + 1, yoffset + 1, height-(yoffset*2)-2, (width-(xoffset*2)-2));
		}
		else
			murrine_draw_flat_hilight (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, (height-(yoffset*2)-2));
	}
	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8);
	cairo_fill(cr);

	if (widget->glazestyle == 4) {
		if (!slider->horizontal) {
			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
			murrine_draw_curved_hilight_bottom_neg (cr, curve_pos, height, width);
		}
		else
			murrine_draw_curved_hilight_bottom_neg (cr, curve_pos, width, height);
		MurrineRGB shadow;
		murrine_shade (fill, &shadow, 0.96*(1/widget->hilight_ratio));
		cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
		cairo_fill(cr);
	}

	murrine_shade (fill, &hilight, 1.08*widget->hilight_ratio); //makes the inner border brighter
	//the white inner border
	if (widget->roundness < 2) {
		int tmp;
		if (!slider->horizontal) {
			tmp = height;
			height = width;
			width = tmp;
		}
		cairo_rectangle(cr, xoffset + 1.5, yoffset + 1.5, width-(xoffset*2)-3, height-(yoffset*2)-3);		
		cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke(cr);
		//bottom line
		cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
		cairo_move_to (cr, xoffset+1, height-yoffset-1.5);
		cairo_rel_line_to (cr, width-(xoffset*2)-2, 0);
		if (widget->glazestyle == 2) {
			cairo_move_to (cr, width-(xoffset)-1.5, yoffset+2);
			cairo_rel_line_to (cr, 0, height-yoffset*2-3.5);
		}
		cairo_stroke (cr);
		if (tmp == width) {
			tmp = height;
			height = width;
			width = tmp;
		}
	}
	cairo_reset_clip(cr);
	cairo_restore(cr);
	//border
	if (widget->disabled)
		cairo_set_source_rgb (cr, border_disabled.r, border_disabled.g, border_disabled.b);
	else
		cairo_set_source_rgb (cr, border_normal.r, border_normal.g, border_normal.b);
	if (widget->roundness < 2)
		murrine_rounded_rectangle(cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->corners);
	else
		clearlooks_rounded_rectangle(cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
	cairo_stroke(cr);
}

void
murrine_draw_list_view_header (cairo_t *cr,
                                  const MurrineColors          *colors,
                                  const WidgetParameters          *widget,
                                  const ListViewHeaderParameters  *header,
                                  int x, int y, int width, int height)
{
	const MurrineRGB *fill = &colors->bg[widget->state_type];
	MurrineRGB *border = (MurrineRGB*)&colors->shade[3];
	
	cairo_translate (cr, x, y);
	cairo_set_line_width (cr, 1.0);

	/* Draw highlight */
	MurrineRGB hilight;
	murrine_shade (border, &hilight, 1.5);

	if (header->order == MRN_ORDER_FIRST)
	{
		cairo_move_to (cr, 0.5, height-1);
		cairo_line_to (cr, 0.5, 0.5);
	}
	else
		cairo_move_to (cr, 0.0, 0.5);
	
	cairo_line_to (cr, width, 0.5);
	cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
	cairo_stroke (cr);

	//effects
	if (header->style > 0) {
		MurrineRGB hilight_header; 
		murrine_shade (fill, &hilight_header, 1.1*widget->hilight_ratio);
		if (header->style == 1) {
			if (widget->glazestyle > 0) {
				if (widget->glazestyle == 2) {
					cairo_rectangle (cr, 0, 0, width, height);
					cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
					cairo_fill_preserve(cr);
				}
				//rounded fill
				if (widget->glazestyle < 3)
					murrine_draw_curved_hilight (cr, 0, width, height);
				else
					murrine_draw_curved_hilight_neg (cr, 0, width, height);
			}
			else { 
				murrine_draw_flat_hilight (cr, 0 , 0 , width, height);
			}
			
			cairo_set_source_rgba (cr, hilight_header.r, hilight_header.g, hilight_header.b, 0.8);
			cairo_fill (cr);

			if (widget->glazestyle == 4) {
				murrine_draw_curved_hilight_bottom_neg (cr, 0, width, height);
				MurrineRGB shadow;
				murrine_shade (fill, &shadow, 0.96*(1/widget->hilight_ratio));
				cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
				cairo_fill(cr);
			}

			if (widget->glazestyle == 2) {
				cairo_move_to (cr, 0.5, height-2);
				cairo_line_to (cr, 0.5, 1);
				cairo_move_to (cr, 0.0, 0.5);
				cairo_line_to (cr, width, 0.5);
				cairo_set_source_rgb (cr, hilight_header.r, hilight_header.g, hilight_header.b);
				cairo_stroke(cr);
				cairo_move_to (cr, width-1.5, 1);
				cairo_line_to (cr, width-1.5, height-2);
				cairo_move_to (cr, width-1, height-1.5);
				cairo_line_to (cr, 0.0, height-1.5);
				cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
				cairo_stroke(cr);
			}
		}
		else if (header->style == 2) {
			border = (MurrineRGB*)&colors->shade[4];
	
			MurrineRGB shadow_header; 
			murrine_shade (fill, &shadow_header, 0.925);

			cairo_rectangle       (cr, 0.0, height-3.0, width, 2.0);
			cairo_set_source_rgb  (cr, shadow_header.r, shadow_header.g, shadow_header.b);
			cairo_fill            (cr);
		}
	}
	/* Draw bottom border */
	cairo_move_to (cr, 0.0, height-0.5);
	cairo_line_to (cr, width, height-0.5);
	cairo_set_source_rgb (cr, border->r, border->g, border->b);
	cairo_stroke (cr);	
	
	/* Draw resize grip */
	if (header->order != MRN_ORDER_LAST || header->resizable)
	{
		if (header->style == 1 && widget->glazestyle > 0) {
			cairo_set_line_width  (cr, 1.0);
			cairo_translate       (cr, width-0.5, 0);
			
			cairo_move_to         (cr, 0, 0);
			cairo_line_to         (cr, 0, height);
			cairo_set_source_rgb  (cr, border->r, border->g, border->b);
			cairo_stroke          (cr);
		}
		else {
			SeparatorParameters separator;
			separator.horizontal = FALSE;
			
			murrine_draw_separator (cr, colors, widget, &separator, width-1.5, 4.0, 2, height-8.0);
		}
	}
}

/* We can't draw transparent things here, since it will be called on the same
 * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
void
murrine_draw_toolbar (cairo_t *cr,
                         const MurrineColors          *colors,
                         const WidgetParameters          *widget,
                         int x, int y, int width, int height)
{
	MurrineRGB *dark   = (MurrineRGB*)&colors->shade[3];
	MurrineRGB hilight; 
	murrine_shade (dark, &hilight, 1.5);
	
	cairo_set_line_width (cr, 1.0);
	cairo_translate      (cr, x, y);

#ifndef HAVE_MACMENU
	/* Draw highlight */
	cairo_move_to        (cr, 0, 0.5);
	cairo_line_to        (cr, width-1, 0.5);
	cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
	cairo_stroke         (cr);
#endif

	/* Draw shadow */
	cairo_move_to        (cr, 0, height-0.5);
	cairo_line_to        (cr, width-1, height-0.5);
	cairo_set_source_rgb (cr, dark->r, dark->g, dark->b);
	cairo_stroke         (cr);
}

void
murrine_draw_menuitem (cairo_t *cr,
                          const MurrineColors          *colors,
                          const WidgetParameters       *widget,
                          int x, int y, int width, int height, int menuitemstyle)
{
	MurrineRGB *fill   = (MurrineRGB*)&colors->spot[1];
	MurrineRGB *border = (MurrineRGB*)&colors->spot[2];

	cairo_translate      (cr, x, y);
	cairo_set_line_width (cr, 1.0);
	if (widget->roundness < 2)	
		cairo_rectangle (cr, 0, 0, width, height);
	else
		clearlooks_rounded_rectangle  (cr, 0, 0, width, height, widget->roundness, widget->corners);
	cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);

	MurrineRGB hilight;
	murrine_shade (&colors->spot[1], &hilight, 1.1*widget->hilight_ratio);

	if (menuitemstyle == 2) {
		cairo_fill(cr);
		double		tile_pos = 0;
		double		stroke_width;
		int			x_step;
		stroke_width = height*2;
		cairo_save (cr);
		x_step = (((float)stroke_width/10));
		/* Draw strokes */
		while (tile_pos <= width+x_step-2)	{
			cairo_move_to (cr, stroke_width/2-x_step, 0);
			cairo_line_to (cr, stroke_width-x_step,   0);
			cairo_line_to (cr, stroke_width/2-x_step, height);
			cairo_line_to (cr, -x_step, height);
			cairo_translate (cr, stroke_width, 0);
			tile_pos += stroke_width;
		}
		cairo_set_source_rgba (cr, colors->spot[2].r, colors->spot[2].g,  colors->spot[2].b, 0.15);
		cairo_fill (cr);
		cairo_restore (cr);
	}
	else if (menuitemstyle != 0) {
		if (widget->roundness > 1)
			cairo_clip_preserve(cr);
		if (widget->glazestyle > 0) {
			if (widget->glazestyle == 2)
				cairo_fill_preserve (cr);
			else
				cairo_fill(cr);
			//rounded fill
			if (widget->glazestyle < 3)
				murrine_draw_curved_hilight (cr, 0, width, height);
			else
				murrine_draw_curved_hilight_neg (cr, 0, width, height);
		}
		else {
			cairo_fill(cr);
			murrine_draw_flat_hilight (cr, 0, 0, width, height);
		}
		cairo_set_source_rgba 	(cr, hilight.r, hilight.g, hilight.b, 0.8);
		cairo_fill (cr);
		
		if (widget->glazestyle == 4) {
			murrine_draw_curved_hilight_bottom_neg (cr, 0, width, height);
			MurrineRGB shadow;
			murrine_shade (&colors->spot[1], &shadow, 0.96*(1/widget->hilight_ratio));
			cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
			cairo_fill(cr);
		}

		if (widget->glazestyle == 2) {
			cairo_move_to (cr, 1.5, height-2);
			cairo_line_to (cr, 1.5, 2);
			cairo_move_to (cr, 1, 1.5);
			cairo_line_to (cr, width-1, 1.5);
			cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
			cairo_stroke (cr);
			cairo_move_to (cr, width-1.5, 2);
			cairo_line_to (cr, width-1.5, height-2);
			cairo_move_to (cr, width-1, height-1.5);
			cairo_line_to (cr, 1, height-1.5);
			cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
			cairo_stroke (cr);
		}
	}
	else {
		cairo_fill(cr);
		if (widget->roundness < 2)
			murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->corners);
		else
			clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
		cairo_set_source_rgba (cr, colors->spot[2].r, colors->spot[2].g,  colors->spot[2].b, 0.15);
		cairo_fill_preserve (cr);
	}
	if (widget->roundness < 2)
		murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->corners);
	else
		clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
	cairo_set_source_rgba (cr, border->r, border->g, border->b, 0.8);
	cairo_stroke    		(cr);
}

void
murrine_draw_scrollbar_trough (cairo_t *cr,
                                  const MurrineColors           *colors,
                                  const WidgetParameters           *widget,
                                  const ScrollBarParameters        *scrollbar,
                                  int x, int y, int width, int height)
{
	MurrineRGB      *bg     = (MurrineRGB*)&colors->shade[1];
	MurrineRGB      *border = (MurrineRGB*)&colors->shade[3];
	
	cairo_set_line_width (cr, 1);
	
	if (scrollbar->horizontal)
	{
		int tmp = height;
		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
		height = width;
		width = tmp;
	}
	else
	{
		cairo_translate (cr, x, y);	
	}

	/* Draw fill */
	if (widget->roundness < 2)
		cairo_rectangle (cr, 1, 0, width-2, height);
	else
		clearlooks_rounded_rectangle (cr, 1, 0, width-2, height, widget->roundness, widget->corners);
	cairo_set_source_rgba (cr, bg->r, bg->g, bg->b, 0.4);
	cairo_fill (cr);

	/* Draw border */
	if (widget->roundness < 2)
		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
	else
		clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
	cairo_set_source_rgba (cr, border->r, border->g, border->b, 0.8);
	cairo_stroke (cr);
}

void
murrine_draw_scrollbar_stepper (cairo_t *cr,
                                   const MurrineColors             *colors,
                                   const WidgetParameters           *widget,
                                   int x, int y, int width, int height)
{	
	const MurrineRGB *fill            = &colors->bg[widget->state_type];
	const MurrineRGB *border_normal_  = &colors->shade[6];

	MurrineRGB border_normal;
	murrine_shade (border_normal_, &border_normal, 0.95);

	MurrineRGB hilight;
	murrine_shade (fill, &hilight, 1.1*widget->hilight_ratio);

	cairo_translate (cr, x, y);
	cairo_set_line_width (cr, 1.0);
	
	//the border
	border_normal.r = border_normal.r * (0.6) + fill->r * 0.4;
	border_normal.g = border_normal.g * (0.6) + fill->g * 0.4;
	border_normal.b = border_normal.b * (0.6) + fill->b * 0.4;
	
	//fill
	cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
	if (widget->roundness < 2)
		cairo_rectangle(cr, 1, 1, width-2, height-2);		
	else
		clearlooks_rounded_rectangle(cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);	

	cairo_save(cr);
	if (widget->roundness > 1)
		cairo_clip_preserve(cr);

	int curve_pos = 1;
	/* Fix for vertical buttons */
	if (widget->glazestyle > 0) {
		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
		if (widget->glazestyle == 2)
			cairo_fill_preserve(cr);
		else
			cairo_fill(cr);
		//rounded fill
		if (widget->roundness < 2)
			curve_pos = 2;
		if (widget->glazestyle < 3)
			murrine_draw_curved_hilight (cr, curve_pos, width, height);
		else
			murrine_draw_curved_hilight_neg (cr, curve_pos, width, height);
	}
	else {
		cairo_fill(cr);
		murrine_draw_flat_hilight (cr, 1, 1, width-2, height-2);
	}
	
	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8);
	cairo_fill(cr);

	if (widget->glazestyle == 4) {
		murrine_draw_curved_hilight_bottom_neg (cr, curve_pos, width, height);
		MurrineRGB shadow;
		murrine_shade (fill, &shadow, 0.96*(1/widget->hilight_ratio));
		cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
		cairo_fill(cr);
	}

	murrine_shade (fill, &hilight, 1.08*widget->hilight_ratio); //makes the inner border brighter
	//the white inner border
	if (widget->roundness < 2) {
		cairo_rectangle(cr, 1.5, 1.5, width-3, height-3);		
		cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke(cr);
		
		//bottom line
		cairo_set_source_rgb (cr, fill->r, fill->g, fill->b);
		cairo_move_to (cr, 1, height-1.5);
		cairo_rel_line_to (cr, width-2, 0);
		if (widget->glazestyle > 1) {
			cairo_move_to (cr, width-1.5, 2);
			cairo_rel_line_to (cr, 0, height-3.5);
		}
		cairo_stroke (cr);
	}

	cairo_reset_clip(cr);
	cairo_restore (cr);

	cairo_set_source_rgb (cr, border_normal.r, border_normal.g, border_normal.b);
	//border
	if (widget->roundness < 2)
		murrine_rounded_rectangle(cr, 0.5, 0.5, width-1, height-1, widget->corners);
	else
		clearlooks_rounded_rectangle(cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
	cairo_stroke(cr);
}

void
murrine_draw_scrollbar_slider (cairo_t *cr,
                                   const MurrineColors          *colors,
                                   const WidgetParameters          *widget,
                                   const ScrollBarParameters       *scrollbar,
                                   int x, int y, int width, int height)
{
	if (scrollbar->junction & MRN_JUNCTION_BEGIN)
	{
		if (scrollbar->horizontal)
		{
			x -= 1;
			width += 1;
		}
		else
		{
			y -= 1;
			height += 1;
		}
	}
	if (scrollbar->junction & MRN_JUNCTION_END)
	{
		if (scrollbar->horizontal)
			width += 1;
		else
			height += 1;
	}

	//setting colors
	MurrineRGB  fill;
	if (scrollbar->has_color)
		fill    = scrollbar->color;
	else 
		fill    = colors->bg[0];
		
	MurrineRGB *border_ = (MurrineRGB*)&colors->shade[6];
	MurrineRGB border;

	murrine_shade (border_, &border, 0.95);

	MurrineRGB hilight;

	if (widget->prelight)
		murrine_shade (&fill, &fill, 1.05);

	murrine_shade (&fill, &hilight, 1.1*widget->hilight_ratio);

	border.r = border.r * (0.6) + fill.r * 0.4;
	border.g = border.g * (0.6) + fill.g * 0.4;
	border.b = border.b * (0.6) + fill.b * 0.4;

	//begin drawing
	if (scrollbar->horizontal)
		cairo_translate (cr, x, y);	

	else
	{
		int tmp = height;
		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
		height = width;
		width = tmp;
	}

	cairo_set_line_width (cr, 1);

	murrine_rounded_rectangle(cr, 0.5,  0.5, width-1, height-1, widget->corners);
	cairo_set_source_rgb (cr, border.r, border.g, border.b);		
	cairo_stroke(cr); 

	cairo_set_source_rgb (cr, fill.r, fill.g, fill.b);
	cairo_rectangle(cr, 1, 1, width-2, height-2);

	//glass effect
	if (widget->glazestyle > 0) {
		if (widget->glazestyle == 2)
			cairo_fill_preserve(cr);
		else
			cairo_fill(cr);
		//rounded fill
		if (widget->glazestyle < 3)
			murrine_draw_curved_hilight (cr, 1, width, height);
		else
			murrine_draw_curved_hilight_neg (cr, 1, width, height);
	}	
	else {
		cairo_fill(cr);
		murrine_draw_flat_hilight (cr, 1, 1, width-3, height-3);
	}
	
	cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8);
	cairo_fill(cr);

	if (widget->glazestyle == 4) {
		murrine_draw_curved_hilight_bottom_neg (cr, 1, width, height);
		MurrineRGB shadow;
		murrine_shade (&fill, &shadow, 0.96*(1/widget->hilight_ratio));
		cairo_set_source_rgb (cr, shadow.r,shadow.g,shadow.b);
		cairo_fill(cr);
	}

	murrine_shade (&fill, &hilight, 1.08*widget->hilight_ratio);
	if (widget->roundness < 2) {
		//the white inner border
		cairo_rectangle(cr, 1.5, 1.5, width-3, height-3);		
		cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
		cairo_stroke(cr);
		cairo_set_source_rgb (cr, fill.r, fill.g, fill.b);
		cairo_move_to (cr, 1, height-1.5);
		cairo_rel_line_to (cr, width-2, 0);
		if (widget->glazestyle == 2) {
			cairo_move_to (cr, width-1.5, 2);
			cairo_rel_line_to (cr, 0, height-4);
		}
		cairo_stroke (cr);
	}

	/// BIG OPTIONS!!! 6!!!
	MurrineRGB style;
	if (scrollbar->style > 0)
		murrine_shade (&fill, &style, 0.55);

	//Circles
	if (scrollbar->style == 1) {
		int circ_radius = 2;
		int circ_space = 5;
		int i;
		int x1 = circ_space+circ_radius;
		int y1 = height/2;
		for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space) {
			cairo_move_to(cr, i, 1);
			cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
			
			x1 += 2*circ_radius+circ_space;
			
			cairo_close_path(cr);
			cairo_set_source_rgba (cr, style.r, style.g,  style.b, 0.15);
			cairo_fill(cr);
		}
	}

	if (scrollbar->style > 2) {
		//Diagonal strokes
		if (scrollbar->style < 5) {
			cairo_save(cr);
			cairo_rectangle(cr, 1, 1, width-2, height-2);
			cairo_clip(cr);
			cairo_new_path(cr);
			int counter = -width;
			cairo_set_line_width (cr, 5); //stroke width
			cairo_set_source_rgba (cr, style.r, style.g,  style.b, 0.08);
			while (counter < height) {
				cairo_move_to  (cr, width, counter);
				cairo_line_to  (cr, 0, counter+width);
				cairo_stroke   (cr);
				counter += 12;
			}
			cairo_restore (cr);
		}
		//Orizontal strokes
		if (scrollbar->style > 4) {
			int stroke_width = 7;
			int stroke_space = 5;
			int i;
			cairo_set_source_rgba (cr, style.r, style.g,  style.b, 0.08);
			for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space) {
				cairo_move_to(cr, i, 1);
				cairo_rel_line_to(cr, 0, height-2);
				cairo_rel_line_to(cr, stroke_width, 0);
				cairo_rel_line_to(cr, 0, -(height-2));
				cairo_fill(cr);
			}
		}
	}

	//Handle
	if (scrollbar->style > 0 && scrollbar->style % 2 == 0 ) {
		int bar_x = width/2 - 4;
		cairo_translate(cr, 0.5, 0.5);
		int i;
		/*MurrineRGB lines;
		murrine_shade (&fill, &lines, 0.9);*/
		for (i=0; i<3; i++)
		{
			cairo_move_to (cr, bar_x, 4.5);
			cairo_line_to (cr, bar_x, height-5.5);
			cairo_set_source_rgba (cr, border.r, border.g, border.b, 1);
			cairo_stroke (cr);
			
			bar_x += 3;
		}
	}
}

void
murrine_draw_statusbar (cairo_t *cr,
                           const MurrineColors          *colors,
                           const WidgetParameters          *widget,
                           int x, int y, int width, int height)
{	
	MurrineRGB *dark   = (MurrineRGB*)&colors->shade[3];
	MurrineRGB hilight; 
	murrine_shade (dark, &hilight, 1.5);

	cairo_set_line_width  (cr, 1);
	cairo_translate       (cr, x, y+0.5);
	cairo_move_to         (cr, 0, 0);
	cairo_line_to         (cr, width, 0);
	cairo_set_source_rgb  (cr, dark->r, dark->g, dark->b);
	cairo_stroke          (cr);

	cairo_translate       (cr, 0, 1);
	cairo_move_to         (cr, 0, 0);
	cairo_line_to         (cr, width, 0);
	cairo_set_source_rgb  (cr, hilight.r, hilight.g, hilight.b);
	cairo_stroke          (cr);
}

void
murrine_draw_menu_frame (cairo_t *cr,
                            const MurrineColors          *colors,
                            const WidgetParameters          *widget,
                            int x, int y, int width, int height)
{
	MurrineRGB *border = (MurrineRGB*)&colors->shade[5];
	cairo_translate      (cr, x, y);
	cairo_set_line_width (cr, 1);
	cairo_rectangle      (cr, 0.5, 0.5, width-1, height-1);
	cairo_set_source_rgb (cr, border->r, border->g, border->b);
	
	cairo_stroke         (cr);
}

void
murrine_draw_handle (cairo_t *cr,
                        const MurrineColors          *colors,
                        const WidgetParameters          *widget,
                        const HandleParameters          *handle,
                        int x, int y, int width, int height)
{
	MurrineRGB *dark  = (MurrineRGB*)&colors->shade[3];

	int bar_height;
	int bar_width  = 4;
	int i, bar_y = 1;
	int num_bars, bar_spacing;
	num_bars    = 3;
	bar_spacing = 3;
	bar_height = num_bars * bar_spacing;
	
	if (handle->horizontal)
	{
		int tmp = height;
		rotate_mirror_translate (cr, M_PI/2, x + 0.5 + width/2 - bar_height/2, y + height/2 - bar_width/2, FALSE, FALSE);
		height = width;
		width = tmp;
	}
	else
	{
		cairo_translate (cr, x + width/2 - bar_width/2, y + height/2 - bar_height/2 + 0.5);
	}
	
	cairo_set_line_width (cr, 1);

	for (i=0; i<num_bars; i++)
	{
		cairo_move_to (cr, 0, bar_y);
		cairo_line_to (cr, bar_width, bar_y);
		cairo_set_source_rgb (cr, dark->r, dark->g, dark->b);
		cairo_stroke (cr);
		
		bar_y += bar_spacing;
	}
}

static void
murrine_draw_normal_arrow (cairo_t *cr, MurrineRGB *color,
                              double x, double y, double width, double height)
{
	const int ARROW_WIDTH  = 7.0;
	const int ARROW_HEIGHT = 4.0;

	cairo_set_line_width (cr, 1);
	
	cairo_move_to   (cr, -ARROW_WIDTH/2, -ARROW_HEIGHT/2);
	cairo_line_to   (cr, 0, ARROW_HEIGHT/2);
	cairo_line_to   (cr, ARROW_WIDTH/2, -ARROW_HEIGHT/2);
	
	cairo_set_source_rgb (cr, color->r, color->g, color->b);
	cairo_stroke (cr);	
}

static void
murrine_draw_combo_arrow (cairo_t *cr, MurrineRGB *color,
                             double x, double y, double width, double height)
{
	const int ARROW_WIDTH   = 7.0;
	const int ARROW_HEIGHT  = 4.0;
	const int ARROW_SPACING = 8;
	
	cairo_set_line_width (cr, 1);

	y -= ARROW_SPACING/2;
	
	cairo_move_to (cr, -ARROW_WIDTH/2, y + ARROW_HEIGHT/2);
	cairo_line_to   (cr, 0, y + -ARROW_HEIGHT/2);
	cairo_line_to   (cr, ARROW_WIDTH/2, y + ARROW_HEIGHT/2);
	cairo_set_source_rgb (cr, color->r, color->g, color->b);	
	cairo_stroke (cr);
	
	y += ARROW_SPACING;
	
	cairo_move_to (cr, -ARROW_WIDTH/2, y + -ARROW_HEIGHT/2);
	cairo_line_to   (cr, 0, y + ARROW_HEIGHT/2);
	cairo_line_to   (cr, ARROW_WIDTH/2, y + -ARROW_HEIGHT/2);
	cairo_set_source_rgb (cr, color->r, color->g, color->b);	
	cairo_stroke (cr);
}

static void
_murrine_draw_arrow (cairo_t *cr, MurrineRGB *color,
                        MurrineDirection dir, MurrineArrowType type,
                        double x, double y, double width, double height)
{
	double rotate;
	
	if (dir == MRN_DIRECTION_LEFT)
		rotate = M_PI*1.5;
	else if (dir == MRN_DIRECTION_RIGHT)
		rotate = M_PI*0.5;
	else if (dir == MRN_DIRECTION_UP)
		rotate = M_PI;
	else
		rotate = 0;
	
	if (type == MRN_ARROW_NORMAL)
	{		
		rotate_mirror_translate (cr, rotate, x, y, FALSE, FALSE);		
		murrine_draw_normal_arrow (cr, color, 0, 0, width, height);
	}
	else if (type == MRN_ARROW_COMBO)
	{
		cairo_translate (cr, x, y);
		murrine_draw_combo_arrow (cr, color, 0, 0, width, height);
	}
}

void
murrine_draw_arrow (cairo_t *cr,
                       const MurrineColors          *colors,
                       const WidgetParameters          *widget,
                       const ArrowParameters           *arrow,
                       int x, int y, int width, int height)
{
	MurrineRGB *color = (MurrineRGB*)&colors->text[widget->state_type];
	gdouble tx, ty;
	
	if (arrow->direction == MRN_DIRECTION_DOWN || arrow->direction == MRN_DIRECTION_UP)
	{
		tx = x + width/2;
		ty = (y + height/2) + 0.5;
	}
	else
	{
		tx = (x + width/2) + 0.5;
		ty = y + height/2;
	}
	
	if (widget->disabled)
	{
		_murrine_draw_arrow (cr, (MurrineRGB*)&colors->shade[0],
		                        arrow->direction, arrow->type,
		                        tx+0.5, ty+0.5, width, height);
		
		color = (MurrineRGB*)&colors->text[widget->state_type];
	}

	cairo_identity_matrix (cr);
	
	_murrine_draw_arrow (cr, color, arrow->direction, arrow->type, tx, ty, width, height);
}

void
murrine_draw_resize_grip (cairo_t *cr,
                             const MurrineColors          *colors,
                             const WidgetParameters          *widget,
                             const ResizeGripParameters      *grip,
                             int x, int y, int width, int height)
{
	MurrineRGB *dark   = (MurrineRGB*)&colors->shade[4];
	MurrineRGB hilight; 
	murrine_shade (dark, &hilight, 1.5);
	int lx, ly;
 
	cairo_set_line_width (cr, 1);

	for (ly=0; ly<4; ly++) // vertically, four rows of dots
	{
		for (lx=0; lx<=ly; lx++) // horizontally
		{
			int ny = (3.5-ly) * 3;
			int nx = lx * 3;

			cairo_set_source_rgb (cr, hilight.r, hilight.g, hilight.b);
			cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 2, 2);
			cairo_fill (cr);

			cairo_set_source_rgb (cr, dark->r, dark->g, dark->b);
			cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 1, 1);
			cairo_fill (cr);
		}
	}
}
